﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Dune.Business.Domain.AssemblyCodes;
using Dune.Common;
using Dune.Common.ComponentModel;
using Dune.Common.Utils;
using NHibernate;
using NHibernate.Expression;
using NHibernate.Type;

namespace Dune.DAL.Managers
{
    class AssemblyStorage : AbstractManager<AssemblyCode, AssemblyCodeKey>, IAssemblyCodeManager, IAssemblyRepository
    {
        public AssemblyCode Get(AssemblyCodeKey id)
        {
            return Session.Get<AssemblyCode>(id);
        }

        public Assembly Get(string name, Version version)
        {
            AssemblyCode assemblyCode = Get(new AssemblyCodeKey(name, version.ToString()));
            if (assemblyCode == null)
                return null;
            return Assembly.Load(assemblyCode.Code);
        }


        public int DeleteById(AssemblyCodeKey key)
        {
            return Session.Delete(" from AssemblyCode ac where ac.Id.AssemblyName=? AND ac.Id.AssemblyVersion=?",
                new object[] { key.AssemblyName, key.AssemblyVersion },
                new IType[] { TypeFactory.GetAnsiStringType(50), TypeFactory.GetAnsiStringType(50) });
        }

        public ICollection<AssemblyCode> Find(FetchOptions fetchOptions, AssemblyCodeFilter filter)
        {
            ICriteria criteria = CreateCriteria(fetchOptions);
            AddRestrictions(criteria, filter);
            return criteria.List<AssemblyCode>();
        }

        public int Count(AssemblyCodeFilter filter)
        {
            ICriteria criteria = CreateCriteria();
            AddRestrictions(criteria, filter);
            //            SetupFTSCriteria(filter, criteria);
            criteria.SetProjection(Projections.RowCount());
            return (int)criteria.List()[0];
        }

        private void AddRestrictions(ICriteria criteria, AssemblyCodeFilter filter)
        {
            if (!StringUtils.IsBlankOrNull(filter.AssmeblyName))
                criteria.Add(Expression.Eq("Id.AssemblyName", filter.AssmeblyName));

            if (filter.Version != null)
                criteria.Add(Expression.Eq("Id.AssemblyVersion", filter.Version.ToString()));

        }

        public override void Save(AssemblyCode obj)
        {
            DateTime stamp = DateTime.Now;
            if (IsNewObject(obj))
                obj.CreateDate = stamp;

            obj.ModifyDate = stamp;

            base.Save(obj);
        }
    }
}